﻿using System;
using System.Reflection;
using SimpleServiceBus.Bus.MessageManagement.MessageHandling;
using SimpleServiceBus.Bus.Pipeline;
using SimpleServiceBus.Utilities.ObjectBuilder;

namespace SimpleServiceBus.Bus.MessageManagement.MessageHandling
{
    public class MessageHandlerBinding : MessageTypePredicate,IMessageHandlerBinding
    {
        public MessageHandlerBinding(Type handlerType, Type messageType)
        {
            var signature = new[] {messageType, typeof (IMessageContext)};
            HandlerMethod = handlerType.GetMethod("Handle", signature);
            if (HandlerMethod == null)
                throw new ArgumentException(handlerType.Name + " does not implement a Handle method for " + messageType);
            HandlerType = handlerType;
            MessageType = messageType;
        }

        public Type HandlerType { get; set; }
        public MethodInfo HandlerMethod { get; set; }

        #region IMessageHandlerBinding Members

        public void Handle(object message, IMessageContext context)
        {
            var factory = context.GetLocalService<IObjectBuilderService>();

            object handler = factory.BuildObject(HandlerType);
            if (handler == null)
                throw new Exception("MessageHandler " + HandlerType.Name + " could not be created.");

            HandlerMethod.Invoke(handler, new[] {message, context});
        }

        #endregion
    }
}